package com.letoken.platform.repo.web3;

import com.letoken.platform.repo.wallet.manager.Web3ChainProviderManager;
import com.letoken.platform.repo.web3.provider.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.Hashtable;

/**
 * @author letokenlabs
 * @date 2022/12/14$
 */
@Slf4j
@Component
public class EvmProvider {

    private static Web3ChainProviderManager web3ChainProviderManager;

    @Autowired
    private Web3ChainProviderManager _web3ChainProviderManager;

    private static final Object _locker = new Object();
    private static Hashtable hash = new Hashtable();

    @PostConstruct
    public void init(){
        web3ChainProviderManager = _web3ChainProviderManager;
    }
    

    /**
     * 创建缓存对象实例
     *
     * @param network 公链名称或公链ID (bsc/eth,97/1)(小写）
     * @return
     */
    public static IEvmProvider getInstance(String network)
    {
        if (StringUtils.isEmpty(network))
            network = "bsc";

        IEvmProvider instance = hash.containsKey(network) ? (IEvmProvider)hash.get(network) : null;
        if (instance == null)
        {
            synchronized  (_locker)
            {
                instance = (IEvmProvider)hash.get(network);
                if (instance == null)
                {
                    instance = init(network);
                    hash.put(network, instance);
                }
            }
        }
        return instance;
    }

    /**
     * 初始化缓存对象实例
     *
     * @param network 公链名称或公链ID (bsc/eth,97/1)
     * @return
     */
    private static IEvmProvider init(String network) {
        IEvmProvider instance = null;
        EvmBaseProvider provider;
        try {
            switch (network) {
                case "okc":
                    provider = new OkcProvider();
                    break;
                default:
                    provider = new EvmBaseProvider();
                    break;
            }
            if (provider != null) {
                provider.init(web3ChainProviderManager.getProvider(network));
                instance = provider;
            }
        } catch (Exception ex) {
            log.error("EvmProvider(" + network + ") init error!" + ex.getMessage());
        }

        return instance;
    }

}
